package drds.data_propagate.driver.packets;

import drds.data_propagate.driver.utils.ByteHelper;
import lombok.Getter;
import lombok.Setter;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class GtidSetImpl implements GtidSet {
    @Setter
    @Getter
    public Map<String, UuidSet> sidToUuidSetMap;

    /**
     * 解析如下格式的字符串为MysqlGTIDSet: 726757ad-4455-11e8-ae04-0242ac110002:1 =>
     * GtidSetImpl{ sidToUuidSetMap: { 726757ad-4455-11e8-ae04-0242ac110002: UuidSet{ sid:
     * 726757ad-4455-11e8-ae04-0242ac110002, intervalList: [{start:1, stop:2}] } } }
     * 726757ad-4455-11e8-ae04-0242ac110002:1-3 => GtidSetImpl{ sidToUuidSetMap: {
     * 726757ad-4455-11e8-ae04-0242ac110002: UuidSet{ sid:
     * 726757ad-4455-11e8-ae04-0242ac110002, intervalList: [{start:1, stop:4}] } } }
     * 726757ad-4455-11e8-ae04-0242ac110002:1-3:4 => GtidSetImpl{ sidToUuidSetMap: {
     * 726757ad-4455-11e8-ae04-0242ac110002: UuidSet{ sid:
     * 726757ad-4455-11e8-ae04-0242ac110002, intervalList: [{start:1, stop:5}] } } }
     * 726757ad-4455-11e8-ae04-0242ac110002:1-3:7-9 => GtidSetImpl{ sidToUuidSetMap: {
     * 726757ad-4455-11e8-ae04-0242ac110002: UuidSet{ sid:
     * 726757ad-4455-11e8-ae04-0242ac110002, intervalList: [{start:1, stop:4},
     * {start:7, stop: 10}] } } } 726757ad-4455-11e8-ae04-0242ac110002:1-3,726757
     * ad-4455-11e8-ae04-0242ac110003:4 => GtidSetImpl{ sidToUuidSetMap: {
     * 726757ad-4455-11e8-ae04-0242ac110002: UuidSet{ sid:
     * 726757ad-4455-11e8-ae04-0242ac110002, intervalList: [{start:1, stop:4}] },
     * 726757ad-4455-11e8-ae04-0242ac110003: UuidSet{ sid:
     * 726757ad-4455-11e8-ae04-0242ac110002, intervalList: [{start:4, stop:5}] } } }
     */
    public static GtidSetImpl parse(String uuidSetStringsString) {
        Map<String, UuidSet> sidToUuidSetMap;

        if (uuidSetStringsString == null || uuidSetStringsString.length() < 1) {
            sidToUuidSetMap = new HashMap<String, UuidSet>();
        } else {
            // 存在多个GTID时会有回车符
            String[] uuidSetStrings = uuidSetStringsString.replaceAll("\n", "").split(",");
            sidToUuidSetMap = new HashMap<String, UuidSet>(uuidSetStrings.length);
            for (int i = 0; i < uuidSetStrings.length; i++) {
                UuidSet uuidSet = UuidSet.parse(uuidSetStrings[i]);
                sidToUuidSetMap.put(uuidSet.sid.toString(), uuidSet);
            }
        }

        GtidSetImpl gtidSet = new GtidSetImpl();
        gtidSet.sidToUuidSetMap = sidToUuidSetMap;

        return gtidSet;
    }

    public byte[] encode() throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ByteHelper.writeUnsignedInt64LittleEndian(sidToUuidSetMap.size(), byteArrayOutputStream);

        for (Map.Entry<String, UuidSet> entry : sidToUuidSetMap.entrySet()) {
            byteArrayOutputStream.write(entry.getValue().encode());
        }

        return byteArrayOutputStream.toByteArray();
    }

    public void update(String string) {
        UuidSet uuidSet = UuidSet.parse(string);
        String sid = uuidSet.sid.toString();
        if (sidToUuidSetMap.containsKey(sid)) {
            sidToUuidSetMap.get(sid).intervalList.addAll(uuidSet.intervalList);
            sidToUuidSetMap.get(sid).intervalList = UuidSet.combine(sidToUuidSetMap.get(sid).intervalList);
        } else {
            sidToUuidSetMap.put(sid, uuidSet);
        }
    }

    @Override
    public boolean equals(Object object) {
        if (object == null)
            return false;
        if (this == object)
            return true;

        GtidSetImpl gtidSet = (GtidSetImpl) object;
        if (gtidSet.sidToUuidSetMap == null)
            return false;

        for (Map.Entry<String, UuidSet> entry : sidToUuidSetMap.entrySet()) {
            if (!entry.getValue().equals(gtidSet.sidToUuidSetMap.get(entry.getKey()))) {
                return false;
            }
        }

        return true;
    }


}
